const userListEle = document.querySelector('#user-list') //tobody
const modalDetailEle = document.getElementById("modal-detail")
/*-------页面配置---------- */
let currentPage = 1
let pageSize = 20
let pageCount = 1

/*--------------网络请求相关---------------*/
const baseUrl = "http://47.105.173.95:3000/api/users"
//封装ajax方法
function ajaxGet(url, callback) {
    //#1.创建xhr实例
    const xhr = new XMLHttpRequest()
    //#2.初始化一个请求
    xhr.open('GET', url)
    // xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
    // xhr.setRequestHeader("Content-type","application/json");
    //#3.发送请求
    xhr.send()
    //#4.监听xhr的readystate的变化，使用onreadystatechange函数
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            const res = JSON.parse(xhr.responseText)
            if (typeof callback == 'function') {
                callback(res)
            }
        }
    }
};
//ajax patch方法
function ajaxPatch(url, data, callback) {
    //#1.创建xhr实例
    const xhr = new XMLHttpRequest()
    //#2.初始化一个请求
    xhr.open('PATCH', url)
    xhr.setRequestHeader("Content-Type", "application/json")
    //#3.发送请求
    xhr.send(JSON.stringify(data))
    //#4.监听xhr的readystate的变化，使用onreadystatechange函数
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            const res = JSON.parse(xhr.responseText)
            if (typeof callback == 'function') {
                callback(res)
            }
        }
    }
}
//ajax Post方法
function ajaxPost(url, data, callback) {
    //#1.创建xhr实例
    const xhr = new XMLHttpRequest()
    //#2.初始化一个请求
    xhr.open('POST', url)
    xhr.setRequestHeader("Content-Type", "application/json")
    //#3.发送请求
    xhr.send(JSON.stringify(data))
    //#4.监听xhr的readystate的变化，使用onreadystatechange函数
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            const res = JSON.parse(xhr.responseText)
            if (typeof callback == 'function') {
                callback(res)
            }
        }
    }
};

function ajax(url, option) {
    function joinUrl(url, data) {
        let query = '?'
        for (let key in data) {
            const value = data[key]
            query += `&${key}=${value}`
        }
        //如果baseUrl以/结尾则删除/
        url = url.endsWith('/') ? url.slice(0, -1) : url
        return url + query.replace('&', '')
    };
    const method = (option.method || 'get').toUpperCase()
    const hKey = "Content-type"
    let hValue;
    let dataStr;
    if (method == "GET" || method == "DELETE") {
        hValue = "application/x-www-form-urlencoded"
        url = joinUrl(url, option.data)
    } else {
        hValue = "application/json"
        dataStr = JSON.stringify(option.data)
    }
    const xhr = new XMLHttpRequest()
    xhr.open(method, url)
    xhr.setRequestHeader(hKey, hValue)
    //#3.发送请求
    xhr.send(dataStr)
    //#4.监听xhr的readystate的变化，使用onreadystatechange函数
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4) {
            const res = JSON.parse(xhr.responseText)
            if (xhr.status >= 200 && xhr.status < 300) {
                if (typeof option.success == 'function') {
                    option.success(res)
                }
            } else {
                if (typeof option.error == 'function') {
                    option.error(res, xhr)
                }
            }

        }
    }

}


//根据查询参数获取用户
// function getUsers(params, callback) {
//     const url = joinParams(baseUrl, params)
//     ajaxGet(url, function (res) {
//         handleResponse(res, callback)
//     })
// }
function getUsers(params, success, error) {
    ajax(baseUrl, {
        data: params,
        success: function (res) {
            success(res.results)
        },
        error: function (res, xhr) {
            alert(res.msg)
            error(res, xhr)
        }
    })
    // ajaxGet(url, function (res) {
    //     handleResponse(res, callback)
    // })
}
//把查询对象参数拼接在Url上面
function joinParams(url, params) {
    let query = '?'
    for (let key in params) {
        const value = params[key]
        query += `&${key}=${value}`
    }
    //如果baseUrl以/结尾则删除/
    url = url.endsWith('/') ? url.slice(0, -1) : url
    return baseUrl + query.replace('&', '')
};

//查询用户处理返回数据
function handleResponse(res, success, error) {
    if (res.code == 0) {
        if (typeof success == 'function') {
            success(res.results)
        }
    } else {
        alert(res.msg)
        if (typeof error == 'function') {
            error(res)
        }
    }
}


/*-------------用户列表数据相关--------------- */
//初始化用户数据
(function initUsers() {
    getUsersByPagination(currentPage, pageSize, function (data) {
        renderUserList(data.users)
        renderPagination(data.page_count)
        //激活当前page
        pageActive(currentPage)
    })
})()
//渲染用户列表数据
function renderUserList(users) {
    let html = ''
    for (let i = 0; i < users.length; i++) {
        let user = users[i]
        let trHtml = `
        <tr>
            <th>${user.id}</th>
            <th>${user.username}</th>
            <th>${user.gender == 0 ? '男' : '女'}</th>
            <th>${user.telephone}</th>
            <th>${user.email}</th>
            <th>
                <button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#modal-detail" data-id=${user.id} data-type="detail">详细</button>
                <button type="button" class="btn btn-danger btn-sm" data-id=${user.id} data-type="delete">删除</button>
            </th>
        </tr>`
        html += trHtml
    }
    userListEle.innerHTML = html
};
//给用户列表按钮绑定对应的事件
(function bindUserList() {
    userListEle.addEventListener('click', function (e) {
        const clickElement = e.target
        if (clickElement.tagName == 'BUTTON') {
            const id = clickElement.dataset.id //获取点击的详细按钮对应的id
            if (clickElement.dataset.type == 'detail') {
                //点击的是详细按钮
                getUsers({ id: id }, function (data) {
                    setDetailFormModalState('view')
                    setFormValue(detailFormFieldOption, data.users[0])
                    currentUser = data.users[0]

                })
            } else if (clickElement.dataset.type == 'delete') {
                //删除操作
                //TODO
                console.log('删除操作')
                console.log(id)
                removeUser(id)
            }
        }
    })
})()

/*------------------分页器相关--------------------- */


const paginationElement = document.querySelector('.pagination');
//根据数据内容动态生成分页器
function renderPagination(pageCount = 1) {
    let pageHtml = ''
    for (let i = 1; i <= pageCount; i++) {
        pageHtml += `<li class="${i == 1 ? 'active' : ''}" data-page="${i}"><a href="#" data-page="${i}">${i}</a></li>`
    }
    const html = `
    <li data-page='prev'>
        <a href="#" aria-label="Previous" data-page='prev'>
            <span aria-hidden="true" data-page='prev'>&laquo;</span>
        </a>
    </li>
    ${pageHtml}
    <li data-page="next">
        <a href="#" aria-label="Next" data-page='next'>
            <span aria-hidden="true" data-page='next'>&raquo;</span>
        </a>
    </li>`
    paginationElement.innerHTML = html
}
//给分页器绑定事件，注意：自调用函数上面一句代码必须用;结束
(function bindPaginationClick() {
    paginationElement.addEventListener('click', function (e) {
        e.preventDefault()
        clickElement = e.target
        if (clickElement.tagName == 'A' || clickElement.tagName == 'SPAN') {
            const page = clickElement.dataset.page //数字，字符串'next',字符串'prev'
            handleSwitchpage(page, pageSize)
        }
    })
})()
//处理切换页面
function handleSwitchpage(page = currentPage, limit = pageCount) {
    console.log('页面切换函数')
    let _page;
    if (!isNaN(page)) {//如果Page是数字
        if (page == currentPage) { return }
        _page = parseInt(page)
    } else if (page == "next") {//如果是下一页
        //如果当前页面已经是最大页
        if (currentPage >= pageCount) { return }
        _page = currentPage + 1
    } else if (page == "prev") {//如果是上一页
        //如果当前页面已经是最小页
        if (currentPage <= 1) { return }
        _page = currentPage - 1
    } else {
        alert('页码错误')
        return
    }
    getUsersByPagination(_page, limit, function (data) {
        console.log(data)
        renderUserList(data.users)
        //激活当前page
        pageActive(currentPage)
    })
}
//根据页码和每页限制获取用户信息
function getUsersByPagination(page, limit, callback) {
    getUsers({ _page: page, _limit: limit }, function (data) {
        //如果数据请求成功把_page赋值给全局变量currentPage
        currentPage = parseInt(data.page)
        pageCount = parseInt(data.page_count)
        pageSize = parseInt(data.page_size)
        //回调
        callback(data)

    })
}
//激活页码
function pageActive(page) {
    const currentPageEle = paginationElement.querySelector(`li[data-page='${page}']`)
    const siblingsEle = currentPageEle.parentElement.children
    for (let i = 0; i < siblingsEle.length; i++) {
        siblingsEle[i].classList.remove('active')
    }
    currentPageEle.classList.add('active')
    //处理下一页和上一页的禁用
    nextPageEle = paginationElement.querySelector(`li[data-page='next']`)
    prevPageEle = paginationElement.querySelector(`li[data-page='prev']`)
    nextPageEle.classList.remove('disabled')
    prevPageEle.classList.remove('disabled')
    if (page >= pageCount) {
        nextPageEle.classList.add('disabled')
    }
    if (page <= 1) {
        prevPageEle.classList.add('disabled')
    }
};
/*------------------用户详细页面以及增加用户模态框框表单相关--------------*/
//用户详细信息表单字段配置
const detailFormFieldOption = {
    id: {
        selector: '#id',//选择器
        dataKey: "id",//对应的返回数据中的键
    },
    username: {//字段名称
        selector: '#username',//选择器
        dataKey: "username",//对应的返回数据中的键
        element: null //输入框元素，由后面的initDetailFormElement函数获取并挂载到此处
    },
    email: {
        selector: '#email',
        dataKey: 'email'
    },
    nickname: {
        selector: "#nickname",
        dataKey: "nicheng"
    },
    telephone: {
        selector: '#telephone',
        dataKey: "telephone"
    },
    birthday: {
        selector: '#birthday',
        dataKey: "birthday"
    },
    gender: {
        selector: "[name=gender]",//checkbox和radio推荐使用name做为选择器
        dataKey: 'gender'
    },
    state: {
        selector: "#state",
        dataKey: 'state'
    },
    addr: {
        selector: "#addr",
        dataKey: 'address'
    },
    loginTime: {
        selector: "#login-time",
        dataKey: 'time'
    },
    intro: {
        selector: "#intro",
        dataKey: 'intro'
    },
    permission: {
        selector: "[name='permission']",
        dataKey: 'permission'
    }
};
let currentUser = {};
//用户详细信息表单状态，read / write
let detailFormState = 'read'; //'read'仅仅只读，'write' 可写
let detailFormModalState = 'view';//模态框+表单，状态三种：查看->view、修改->update、新增->add
//用户详细表单的修改/保存按钮
const modalOkBtn = document.getElementById('modal-detail-ok');
//把所有字段对应的输入框找到并挂载到detailFormFieldOption里面字段的element键中
(function initForm() {
    for (let field in formFieldOption) {
        const selector = formFieldOption[field].selector
        const element = document.querySelectorAll(selector)
        if (element.length == 1) {
            formFieldOption[field].element = element[0]
        } else if (element.length > 1) {
            formFieldOption[field].element = Array.from(element)
        } else {
            formFieldOption[field].element = null
        }
    }
})(formFieldOption)

//根据状态设置模态框+表单，状态三种：查看->view、修改->update、新增->add，默认为查看状态
function setDetailFormModalState(state = 'view') {
    let modalOption = {
        element: modalDetailEle,
        title: '查看用户详细信息',
        okBtn: {
            text: '修改',
            data: {
                mode: 'view',//view,update,add
            },
            type: 'warning'
        }
    }
    let formState = 'read'
    if (state == 'view') {
        modalOption.title = '查看用户详细信息',
            modalOption.okBtn = {
                text: '修改',
                data: {
                    mode: 'update'
                },
                type: 'warning'
            }
        formState = 'read'
    } else if (state == 'update') {
        modalOption.title = '修改用户详细信息',
            modalOption.okBtn = {
                text: '保存',
                data: {
                    mode: 'saveUpate'
                },
                type: 'danger'
            }
        formState = 'write'
    } else if (state == 'add') {
        modalOption.title = '新增用户详细信息',
            modalOption.okBtn = {
                text: '增加',
                data: {
                    mode: 'add'
                },
                type: 'success'
            }
        formState = 'write'
        //清空表单内容
        // clearFormValue(detailFormFieldOption)
    } else {
        throw Error('模态框表单状态不合法')
    }
    //更新全局变量
    detailFormModalState = state
    //设置表单状态
    setFormState(formState)
    //设置模态框
    setModal(modalOption)
}


//更新用户数据
function updateUser(formFieldOption, success, error) {
    const formData = getFormValue(formFieldOption)
    //更改的数据
    const diffData = {}
    for (let key in formData) {
        if (currentUser[key] != formData[key]) {
            diffData[key] = formData[key]
        }
    }
    const url = baseUrl + `/${formData.id}`
    ajaxPatch(url, diffData, function (res) {
        handleResponse(res, success, error)
    })
}

//给模态框表单按钮绑定点击事件
(function bindModalForm() {
    //给Ok按钮绑定事件
    modalOkBtn.addEventListener('click', function (e) {
        if (detailFormModalState == 'view') {
            setDetailFormModalState('update')
        } else if (detailFormModalState == 'update') {
            //更新数据
            updateUser(detailFormFieldOption, function (data) {
                alert('数据更改成功')
                //用更新后返回的数据设置表单数据
                setFormValue(detailFormFieldOption, data.users)
                //更新本地currentUser
                // currentUser = res.results.users
            }, function (res) {
                setFormValue(detailFormFieldOption, currentUser)
            })
            //不管是否失败都把状态设为查看
            setDetailFormModalState('view')
        } else if (detailFormModalState == 'add') {
            //'新增用户'
            const userData = getFormValue(detailFormFieldOption)
            addUser(userData, function (data) {
                alert('新增用户成功')
                currentUser = data.users
                setFormValue(detailFormFieldOption, currentUser)
                //用户新增成功后刷新页面
                getUsersByPagination(currentPage, pageSize, function (data) {
                    renderUserList(data.users)
                    renderPagination(data.page_count)
                    //激活当前page
                    pageActive(currentPage)
                })
            })
            setDetailFormModalState('view')
        }

    })
    //监听模态框关闭，模态框关闭后把表单状态设置read
    $('#modal-detail').on('hidden.bs.modal', function (e) {
        setDetailFormModalState('view')
    })
})()
/*----------------------------模态框通用-------------------------------- */
//模态框设置
function setModal(option) {
    const modal = option.element || document.querySelector(option.selector)
    if (!modal) { throw Error('未找要设置到模态框') }
    //模态框顶部标题
    if (option.title != undefined) { modal.querySelector('.modal-title').innerText = option.title }
    if (option.okBtn) {
        const okBtnEle = modal.querySelector("button[data-type='ok']")
        //ok按钮是否显示
        option.okBtn.show == false ? okBtnEle.style.display = 'none' : okBtnEle.style.display = 'inline-block'
        //ok按钮文字
        option.okBtn.text != undefined ? okBtnEle.innerText = option.okBtn.text : null
        //ok按钮文字类型
        if (option.okBtn.type) {
            okBtnEle.className = okBtnEle.className.replace(/btn-\w+/, `btn-${option.okBtn.type}`)
        }
        //OK按钮自定义数据
        if (option.okBtn.data) {
            for (let key in option.okBtn.data) {
                okBtnEle.dataset[key] = option.okBtn.data[key]
            }
        }
    }
    if (option.cancleBtn) {
        const cancleBtnEle = modal.querySelector("button[data-type='cancle']")
        option.cancleBtn.show == false ? cancleBtnEle.style.display = 'none' : cancleBtnEle.style.display = 'inline-block'
        option.cancleBtn.text != undefined ? cancleBtnEle.innerText = option.cancleBtn.text : null
        if (option.cancleBtn.type) {
            cancleBtnEle.className = cancleBtnEle.className.replace(/btn-\w+/, `btn-${option.cancleBtn.type}`)
        }
        if (option.cancleBtn.data) {
            for (let key in option.cancleBtn.data) {
                cancleBtnEle.dataset[key] = option.cancleBtn.data[key]
            }
        }
    }
    //模态框内容
    if (option.content) { modal.querySelector('.modal-body').innerHTML = option.content }

};
/*------------------表单相关------------------------*/


//设置表单状态，读或者写
function setFormState(state) {
    //设置表单状态
    const flag = state == 'read' ? true : false
    for (let field in detailFormFieldOption) {
        element = detailFormFieldOption[field].element
        if (Array.isArray(element)) {//如果是 radio或者checkbox选项组时
            element.forEach(item => { item.disabled = flag })
        } else if (element.type == 'select-one') {//如果是 select
            element.disabled = flag
        } else {
            element.readOnly = flag
        }
    }
    detailFormState = state
};
/*-------------------添加用户相关---------------- */
(function bindAddUser() {
    const addUserEle = document.getElementById('add-user')
    addUserEle.onclick = function () {
        clearFormValue(detailFormFieldOption)
        setDetailFormModalState('add')
    }
})()
function addUser(user, success, error) {
    ajaxPost(baseUrl, user, function (res) {
        handleResponse(res, success, error)
    })
};
/*------------------头部搜索用户相关----------------------------*/
(function bindSearchUser() {
    const searchBtn = document.getElementById('search')
    const searchIpt = document.getElementById('search-userid')
    searchBtn.onclick = function (e) {
        e.preventDefault()
        const userId = searchIpt.value
        getUsers({ id: userId }, function (data) {

            const user = data.users[0]
            setFormValue(detailFormFieldOption, user)
            $('#modal-detail').modal('show')

        })
    }
})()
/*------------------------删除用户相关---------------------------- */
function removeUser(id, callback) {
    const url = baseUrl + `/${id}`
    ajax(url, {
        method: 'delete',
        success: function (results) {
            //删除成功
        },
        error:function(){
            getUsers({ _page: currentPage, _limit: pageSize }, function (data) {
                
                renderUserList(data.users)
                renderPagination(data.page_count)
                //激活当前page
                pageActive(currentPage)
            })
        }
    })
}

/*
 触发点击事件 -> 请求数据 -> 拿到返回的数据并解析 -> 渲染到网页
*/